/**
 * WebSocket管理器 - 用于处理文档协作编辑的实时通信
 */
class WebSocketManager {
  constructor() {
    this.ws = null;
    this.documentId = null;
    this.isConnected = false;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 5;
    this.reconnectInterval = 3000;
    this.messageHandlers = new Map();

  }

  /**
   * 连接WebSocket
   * @param {number} documentId 文档ID
   * @param {string} token 用户token
   */
  connect(documentId, token) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      console.log('WebSocket已连接');
      return;
    }

    this.documentId = documentId;
    // 获取当前页面的cookie，用于身份验证
    const wsUrl = `ws://localhost:8101/api/ws/document/edit?documentId=${documentId}`;
    
    console.log('尝试连接WebSocket:', wsUrl);
    console.log('当前Cookie:', document.cookie);
    
    try {
      this.ws = new WebSocket(wsUrl);
      this.setupEventHandlers();
    } catch (error) {
      console.error('WebSocket连接失败:', error);
      this.handleReconnect();
    }
  }

  /**
   * 设置WebSocket事件处理器
   */
  setupEventHandlers() {
    this.ws.onopen = () => {
      console.log('WebSocket连接已建立');
      this.isConnected = true;
      this.reconnectAttempts = 0;
      
      // 发送初始化消息
      this.sendMessage({
        type: 'init',
        documentId: this.documentId
      });
    };

    this.ws.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        this.handleMessage(data);
      } catch (error) {
        console.error('解析WebSocket消息失败:', error);
      }
    };

    this.ws.onclose = (event) => {
      console.log('WebSocket连接已关闭', event.code, event.reason);
      this.isConnected = false;
      
      // 根据关闭代码提供具体的错误信息
      if (event.code === 1002) {
        console.error('WebSocket协议错误');
      } else if (event.code === 1003) {
        console.error('WebSocket数据类型错误');
      } else if (event.code === 1006) {
        console.error('WebSocket连接异常关闭，可能是网络问题或服务器拒绝连接');
      } else if (event.code === 1011) {
        console.error('服务器遇到意外情况，可能是权限验证失败');
      }
      
      // 如果不是主动关闭，尝试重连
      if (event.code !== 1000) {
        this.handleReconnect();
      }
    };

    this.ws.onerror = (error) => {
      console.error('WebSocket错误:', error);
      console.error('可能的原因：1. 用户未登录 2. 没有文档权限 3. 服务器未启动 4. 网络连接问题');
      this.isConnected = false;
    };
  }

  /**
   * 处理收到的消息
   * @param {object} message 消息对象
   */
  handleMessage(message) {
    const { type, content, position, operation, user, message: msg } = message;
    
    switch (type) {
      case 'INFO':
        this.triggerHandler('info', { message: msg, user });
        if (content) {
          // 初始文档内容
          this.triggerHandler('documentContent', { content });
        }
        break;
        
      case 'EDIT_ACTION':
        this.triggerHandler('editAction', {
          operation,
          content,
          position,
          user
        });
        break;
        
      case 'CURSOR_MOVE':
        this.triggerHandler('cursorMove', { position, user });
        break;
        
      case 'SELECTION_CHANGE':
        this.triggerHandler('selectionChange', { position, content, user });
        break;
        
      case 'SAVE_VERSION':
        this.triggerHandler('versionSaved', { user, message: msg });
        break;
        
      case 'ERROR':
        this.triggerHandler('error', { message: msg, user });
        break;
        
      default:
        console.warn('未知的消息类型:', type);
    }
  }

  /**
   * 发送编辑操作
   * @param {string} operation 操作类型 (INSERT, DELETE, REPLACE)
   * @param {string} content 内容
   * @param {number} position 位置
   */
  sendEditAction(operation, content, position) {
    if (!this.isConnected) {
      console.warn('WebSocket未连接，无法发送编辑操作');
      return;
    }

    const message = {
      type: 'EDIT_ACTION',
      documentId: this.documentId,
      operation,
      content,
      position,

    };

    this.sendMessage(message);
  }

  /**
   * 发送光标移动
   * @param {number} position 光标位置
   */
  sendCursorMove(position) {
    if (!this.isConnected) {
      return;
    }

    const message = {
      type: 'CURSOR_MOVE',
      documentId: this.documentId,
      position
    };

    this.sendMessage(message);
  }

  /**
   * 发送选择区域变化
   * @param {number} position 开始位置
   * @param {string} content 选择长度或结束位置
   */
  sendSelectionChange(position, content) {
    if (!this.isConnected) {
      return;
    }

    const message = {
      type: 'SELECTION_CHANGE',
      documentId: this.documentId,
      position,
      content
    };

    this.sendMessage(message);
  }

  /**
   * 发送保存版本请求
   */
  sendSaveVersion() {
    if (!this.isConnected) {
      console.warn('WebSocket未连接，无法保存版本');
      return;
    }

    const message = {
      type: 'SAVE_VERSION',
      documentId: this.documentId,

    };

    this.sendMessage(message);
  }

  /**
   * 发送消息
   * @param {object} message 消息对象
   */
  sendMessage(message) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(message));
    } else {
      console.warn('WebSocket未连接，无法发送消息');
    }
  }

  /**
   * 注册消息处理器
   * @param {string} event 事件名称
   * @param {function} handler 处理函数
   */
  on(event, handler) {
    if (!this.messageHandlers.has(event)) {
      this.messageHandlers.set(event, []);
    }
    this.messageHandlers.get(event).push(handler);
  }

  /**
   * 移除消息处理器
   * @param {string} event 事件名称
   * @param {function} handler 处理函数
   */
  off(event, handler) {
    if (this.messageHandlers.has(event)) {
      const handlers = this.messageHandlers.get(event);
      const index = handlers.indexOf(handler);
      if (index > -1) {
        handlers.splice(index, 1);
      }
    }
  }

  /**
   * 触发事件处理器
   * @param {string} event 事件名称
   * @param {any} data 数据
   */
  triggerHandler(event, data) {
    if (this.messageHandlers.has(event)) {
      this.messageHandlers.get(event).forEach(handler => {
        try {
          handler(data);
        } catch (error) {
          console.error(`事件处理器执行失败 [${event}]:`, error);
        }
      });
    }
  }

  /**
   * 处理重连
   */
  handleReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('WebSocket重连次数超过限制');
      this.triggerHandler('reconnectFailed');
      return;
    }

    this.reconnectAttempts++;
    console.log(`尝试重连WebSocket (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);
    
    setTimeout(() => {
      if (this.documentId) {
        this.connect(this.documentId);
      }
    }, this.reconnectInterval);
  }

  /**
   * 断开连接
   */
  disconnect() {
    if (this.ws) {
      this.ws.close(1000, '主动断开连接');
      this.ws = null;
    }
    this.isConnected = false;
    this.documentId = null;
    this.messageHandlers.clear();
  }

  /**
   * 获取连接状态
   */
  getConnectionState() {
    return {
      isConnected: this.isConnected,
      documentId: this.documentId,

      reconnectAttempts: this.reconnectAttempts
    };
  }
}

// 创建全局WebSocket管理器实例
const wsManager = new WebSocketManager();

export default wsManager;